"""
简单容器测试
===========

测试基础的依赖注入容器功能
"""

import pytest
from unittest.mock import Mock, AsyncMock
from dependency_injector import containers, providers


class SimpleTestContainer(containers.DeclarativeContainer):
    """简单的测试容器"""
    
    # 配置
    config = providers.Configuration()
    
    # 简单服务
    cache_service = providers.Factory(Mock)
    websocket_service = providers.Factory(Mock)
    

@pytest.mark.unit
class TestSimpleContainer:
    """简单容器测试类"""
    
    def test_container_creation(self):
        """测试容器创建"""
        container = SimpleTestContainer()
        container.config.from_dict({"environment": "testing"})
        
        assert container is not None
        assert container.config.environment() == "testing"
    
    def test_service_creation(self):
        """测试服务创建"""
        container = SimpleTestContainer()
        
        # 获取服务实例
        cache_service = container.cache_service()
        websocket_service = container.websocket_service()
        
        # 验证服务创建成功
        assert cache_service is not None
        assert websocket_service is not None
        assert isinstance(cache_service, Mock)
        assert isinstance(websocket_service, Mock)
    
    def test_service_override(self):
        """测试服务Override"""
        container = SimpleTestContainer()
        
        # 创建Mock服务
        mock_cache = Mock()
        mock_cache.test_method = Mock(return_value="test_result")
        
        # Override服务
        with container.cache_service.override(providers.Object(mock_cache)):
            cache_service = container.cache_service()
            
            # 验证Override成功
            assert cache_service is mock_cache
            assert cache_service.test_method() == "test_result"
    
    def test_configuration_override(self):
        """测试配置Override"""
        container = SimpleTestContainer()
        
        # 设置初始配置
        container.config.from_dict({"environment": "testing", "debug": False})
        
        # Override配置
        with container.config.override({"environment": "production", "debug": True}):
            assert container.config.environment() == "production"
            assert container.config.debug() is True
        
        # 验证Override结束后恢复
        assert container.config.environment() == "testing"
        assert container.config.debug() is False
    
    @pytest.mark.asyncio
    async def test_async_service_mock(self):
        """测试异步服务Mock"""
        container = SimpleTestContainer()
        
        # 创建异步Mock
        async_mock = AsyncMock()
        async_mock.async_method = AsyncMock(return_value="async_result")
        
        # Override为异步服务
        with container.websocket_service.override(providers.Object(async_mock)):
            ws_service = container.websocket_service()
            
            # 测试异步方法
            result = await ws_service.async_method()
            assert result == "async_result"
            async_mock.async_method.assert_called_once()
    
    def test_singleton_behavior(self):
        """测试单例行为"""
        # 创建单例容器
        class SingletonContainer(containers.DeclarativeContainer):
            singleton_service = providers.Singleton(Mock)
        
        container = SingletonContainer()
        
        # 获取两次实例
        service1 = container.singleton_service()
        service2 = container.singleton_service()
        
        # 验证是同一个实例
        assert service1 is service2
    
    def test_factory_behavior(self):
        """测试工厂行为"""
        container = SimpleTestContainer()
        
        # 获取两次实例
        service1 = container.cache_service()
        service2 = container.cache_service()
        
        # 验证是不同的实例但类型相同
        assert service1 is not service2
        assert isinstance(service1, Mock)
        assert isinstance(service2, Mock)


@pytest.mark.integration
class TestContainerIntegration:
    """容器集成测试"""
    
    def test_multiple_containers(self):
        """测试多个容器"""
        container1 = SimpleTestContainer()
        container2 = SimpleTestContainer()
        
        # 配置不同的环境
        container1.config.from_dict({"environment": "testing"})
        container2.config.from_dict({"environment": "staging"})
        
        # 验证容器独立性
        assert container1.config.environment() == "testing"
        assert container2.config.environment() == "staging"
    
    def test_container_wiring(self):
        """测试容器连接"""
        container = SimpleTestContainer()
        
        # 基本的连接测试
        try:
            # 这里可以测试实际的模块连接
            # container.wire(modules=["tests.unit.test_simple_container"])
            pass
        except Exception as e:
            pytest.fail(f"容器连接失败: {e}")
